﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OracleClient;


namespace CCPSIPCallPush
{
    public class CallPushWoker
    {
        private const int kCallAllowSeconds = 30;
        private const int kCallExpirySeconds = 18;

        /* MySQL寫法
        private const string kMySqlServer = "192.168.52.80";
        private const int kMySqlPort = 3309;
        private const string kMySqlUserId = "ccpsipuser";
        private static byte[] kMySqlKey = { 0x53, 0x59, 0x33, 0x43, 0x36, 0x38, 0x64, 0x33,
                                        0x78, 0x59, 0x57, 0x34, 0x61, 0x4A };
        private const string kMySqlDatabase = "ccpsip";


        /// <summary>
        /// 取得 CCPSIP 的 MySQL 連線字串
        /// </summary>
        /// <returns>MySQL 連線字串</returns>
        private static string getCcpsipConnStr()
        {
            string connStrMySql = String.Format(
              "server={0};port={1};database={2};uid={3};pwd={4};charset=utf8mb4;pooling=true",
              kMySqlServer, kMySqlPort, kMySqlDatabase, kMySqlUserId,
              System.Text.Encoding.UTF8.GetString(kMySqlKey));
            return connStrMySql;
        }*/

        /// <summary>取得Oracle連線字串</summary>
        private static string GetConnStr()
        {
            return "SERVER=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.52.195)(PORT=1521)))(CONNECT_DATA =(SERVER=DEDICATED)(SID=UNIDB)));uid=ISENDER;pwd=aKhJJFA2sWfEsQz0Zm5iwQi9gjiVND";
        }

        public static void DoWork()
        {
            //MySqlConnection connMySql = new MySqlConnection(getCcpsipConnStr());
            OracleConnection connOracle = new OracleConnection(GetConnStr());
            try
            {
                connOracle.Open();


                //【01】取得待推播的來電資料
                //
                string selStr1 = "SELECT pid, CreateTime, Receiver, Caller, IsVideo"
                  + " FROM call_push"
                  + " WHERE Status='0' AND CreateTime>=:CreateTime"
                  + " ORDER BY CreateTime, pid";
                OracleCommand selCmd1 = new OracleCommand(selStr1, connOracle);
                selCmd1.Parameters.Add(":CreateTime", OracleType.DateTime).Value = DateTime.Now.AddSeconds(-1 * kCallAllowSeconds);
                OracleDataAdapter adapter1 = new OracleDataAdapter(selCmd1);
                DataSet dataSet1 = new DataSet();
                adapter1.Fill(dataSet1);

                foreach (DataRow row in dataSet1.Tables[0].Rows)
                {
                    UInt32 DataPID = Convert.ToUInt32(row["pid"]);
                    DateTime CallTime = Convert.ToDateTime(row["CreateTime"]);
                    string Receiver = Convert.ToString(row["Receiver"]);
                    string Caller = Convert.ToString(row["Caller"]);


                    //【02】取得 Device Push Token
                    //
                    DevicePushToken pToken = getPushToken(Receiver, connOracle);

                    if (pToken == null)
                    {
                        //【03-1】記錄略過的推播
                        //
                        string updStr3 = "UPDATE call_push SET Status='N'"
                          + " WHERE pid=:DataPID";
                        OracleCommand updCmd3 = new OracleCommand(updStr3, connOracle);
                        updCmd3.Parameters.Add(":DataPID", OracleType.Number).Value = DataPID;
                        updCmd3.ExecuteNonQuery();
                    }
                    else
                    {
                        string PushMsg = Kit.PhoneKit.getCallerInfo(Caller, CallTime, Receiver);
                        DateTime expiryTime = DateTime.Now.AddSeconds(kCallExpirySeconds);

                        if (pToken.PushType == "IP" || pToken.PushType == "IS")
                        {
                            //iOS APNs Push
                            bool isDev = (pToken.PushType == "IS");
                            Kit.ApnsKit.SendCallPushInHouse(PushMsg, Caller, pToken.PushToken, isDev, DataPID, expiryTime);
                            Kit.ApnsKit.SendCallPushAppStore(PushMsg, Caller, pToken.PushToken, isDev, DataPID, expiryTime);
                        }
                        else if (pToken.PushType == "A")
                        {
                            //Android GCM Push
                            Kit.GCMKit.SendCallPush(PushMsg, Caller, pToken.PushToken, kCallExpirySeconds);
                        }
                        else if (pToken.PushType == "B")
                        {
                            //百度雲推送
                            Baidu.BaiduKit.SendCallPush(PushMsg, Caller, pToken.PushToken, kCallExpirySeconds);
                        }


                        //【03-2】記錄推播完成資訊
                        //
                        string updStr3 = "UPDATE call_push"
                          + " SET Status='F', SentTime=sysdate, PushMsg=:PushMsg"
                          + " WHERE pid=:DataPID";
                        OracleCommand updCmd3 = new OracleCommand(updStr3, connOracle);
                        updCmd3.Parameters.Add(":PushMsg", OracleType.VarChar).Value = PushMsg;
                        updCmd3.Parameters.Add(":DataPID", OracleType.Number).Value = DataPID;
                        updCmd3.ExecuteNonQuery();
                    }
                }
            }
            catch (Exception ex)
            {
                string errorMsg = Kit.ChrisKit.Ex2Xml(ex, true);
                Kit.ChrisKit.AppendToDayLog(errorMsg);
            }
            finally
            {
                connOracle.Close();
            }
        }


        /// <summary>
        /// 取得 SIP 帳號對應的 Device Push Token
        /// </summary>
        /// <param name="SIP_Num">SIP 帳號</param>
        /// <param name="connMySql">已連線的MySqlConnection</param>
        /// <returns>SIP 帳號對應的 Device Push Token</returns>
        //private static DevicePushToken getPushToken(string SIP_Num, MySqlConnection connMySql)
        private static DevicePushToken getPushToken(string SIP_Num, OracleConnection connOracle)
        {
            string selStr1 = "SELECT u.SIP_Num, t.UUID, t.PushType, t.DeviceToken"
              + " FROM reg_user u, device_token t"
              + " WHERE u.SIP_Num=:SIP_Num AND u.Status='Y'"
              + " AND t.Status='Y' AND u.UUID=t.UUID";
            OracleCommand selCmd1 = new OracleCommand(selStr1, connOracle);
            selCmd1.Parameters.Add(":SIP_Num", OracleType.VarChar).Value = SIP_Num;
            OracleDataAdapter adapter1 = new OracleDataAdapter(selCmd1);
            DataSet dataSet1 = new DataSet();
            adapter1.Fill(dataSet1);

            if (dataSet1.Tables[0].Rows.Count > 0)
            {
                DataRow row = dataSet1.Tables[0].Rows[0];
                DevicePushToken deviceToken = new DevicePushToken(row);
                if (!string.IsNullOrEmpty(deviceToken.PushToken))
                    return deviceToken;
            }
            return null;
        }


        /// <summary>
        /// Device Push Token
        /// </summary>
        private class DevicePushToken
        {
            private string _SIPNumber;
            private string _UUID;
            private string _PushType;
            private string _PushToken;

            public string SIPNumber { get { return this._SIPNumber; } }
            public string UUID { get { return this._UUID; } }
            public string PushType { get { return this._PushType; } }
            public string PushToken { get { return this._PushToken; } }

            public DevicePushToken(DataRow row)
            {
                _SIPNumber = Convert.ToString(row["SIP_Num"]);
                _UUID = Convert.ToString(row["UUID"]);
                _PushType = Convert.ToString(row["PushType"]);
                _PushToken = Convert.ToString(row["DeviceToken"]);
            }
        }

    }
}